之前在 Day15 曾示範單獨在 All.vue 發送 API 取得資料後渲染至畫面上,而上篇我們接續完成其他導覽項目所需要的畫面資料時,應該會發現頁面內容的排版是一致的,為了省去在多個元件內重複複製貼上排版程式碼,建議可以將排版樣式包成一個 layout 元件,透過 views 資料夾內的元件引用 layout 元件時,再將資料傳遞過去顯示在畫面上即可。
因此子元件只需要選好資料要傳入的位置,由父元件決定傳入什麼資料。
首先,在 components 資料夾內新增一個 BookList.vue,只將 HTML 排版內容和 SCSS 樣式移駕至此,觀察目前 <template> 和模板語法的結構,會有兩筆資料需要從外部傳入:
{{ navTitle }}
標題名稱{{ bookList.length }}
、v-for
需要遞迴的 bookList
書單資料<div class="BookList">
<h1>{{ navTitle }}</h1>
<p>共計 {{ bookList.length }} 本書</p>
<div class="bookshelf">
<div class="book" v-for="book in bookList" :key="book.id">
<img :src="book.image" alt="book image" />
<p>
原價:<span>{{ book.originPrice }}</span> |
特價:<span class="bargain">{{ book.sellPrice }}</span>
</p>
<p>ISBN:<span>{{ book.ISBN }}</span></p>
<p><span>{{ book.name }}</span></p>
<a :href="book.link" target="_blank">連結</a>
</div>
</div>
</div>
若無特別指定的設置,可使用「陣列形式」。
props: ['navTitle', 'bookList']
若需要更詳細的指定設置,則使用「物件形式」加以說明。
type
:設定型別
props: {
navTitle: String,
bookList: Array,
}
required
:設定是否為必填項目
props: {
navTitle: {
type: [String, Number], // 一次列齊多個可能的型別
required: false,
},
bookList: {
type: Array,
required: true,
},
}
default
設定預設值:當父層引用時沒有指定 navTitle
內容,才會顯示預設值中的內容。
props: {
navTitle: {
type: String,
default: 'BookList',
required: false,
},
bookList: {
type: Array,
required: true,
},
}
傳入靜態資料:傳入的資料已固定,不再改變。
<BookList navTitle="All" />
傳入動態資料:利用 v-bind
綁定資料,若父層資料有所變動,傳入子元件的資料也會同步更新。
<BookList :bookList="books"/>
computed: {
books() {
return this.$store.getters["allBooks"];
},
},